# -*- coding: utf-8 -*-
import sys, os
import urllib, urllib2
import pika, json
import config
import matlab.engine
from functools import wraps
import time
import shutil
import traceback


pathproject = os.getcwd()
pathlogfile = pathproject + "/static/mq.log"

def mkdir(paths):
    rootpath = ""
    for path in paths:
        rootpath = rootpath + path
        if not os.path.exists(rootpath):
            os.mkdir(rootpath)
        rootpath = rootpath + "/"


def log_text(msg):
    flog = open(pathlogfile, 'a+')
    flog.write("[" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "]" + msg + "\n")
    flog.close()
    print(msg)


def log(task_name):
    def task(func):
        @wraps(func)
        def log_text1(*args, **kwargs):
            flog = open('static/mq.log', 'a+')
            log_text(task_name + "任务开始")
            func(*args, **kwargs)
            log_text(task_name + "任务结束")
            flog.close()
        return log_text1

    return task


@log('match')
def match(data):
    """
    计算比赛，一个请求，返回一个计算key,这样可以使得不同的客户端都能够在本系统进行计算
    :return:
    """
    print(sys.version)

    # 下载文件
    callbackurl = data['callbackurl']
    client = data['client']
    id = data['id']
    files = data['files']
    fileRootUrl = data['fileRootUrl']
    localRootDir = data['localRootDir']
    rootpath = os.getcwd()
    matchdir = "static/match/" + client + "/" + str(id)
    mkdir(["static", "match", client, str(id)])

    for fname in files:
        dstfile = matchdir + "/" + fname
        if os.path.exists(localRootDir + fname):
            shutil.copy(localRootDir + fname, dstfile)
        else:
            urllib.urlretrieve(fileRootUrl + fname, dstfile)
        print(fname)

    filepath = os.getcwd() + "/" + matchdir
    os.chdir("code")

    try:
        matlabapp = matlab.engine.start_matlab()
        log_text("启动matlab成功")
        res = matlabapp.LanQi(filepath + "/", 'sensor-R.txt', 'sensor-L.txt', 'angle-R.txt', 'angle-L.txt', 'gps-L.txt',
                        'court-config.txt', 'result-run.txt', 'result-turn.txt', 'result-pass.txt', 'result-step.txt',
                        'result-shoot.txt', nargout=0)
    except:
        res = False
        log_text('比赛' + str(id) + "计算失败")
        log_text(traceback.format_exc())
        print('matlab执行失败')
    else:
        res = True
        log_text('比赛' + str(id) + "计算成功")
        print('matlab执行成功')

    os.chdir(rootpath)
    # 检查是否执行成功

    if res:
        data = {"code": 200,
                "msg": "计算成功",
                "id": id,
                "fileRootUrl": config.MATLAB_WEB_HOST + "/" + matchdir,
                "files": "result-pass.txt,result-run.txt,result-shoot.txt,result-step.txt,result-turn.txt"
                }
    else:
        data = {"code": 2001, "msg": "计算失败", "id": id}

    try:
        urllib2.urlopen(url=callbackurl, data=urllib.urlencode(data))
    except:
        log_text(str(id) + "回调失败")
    else:
        log_text(str(id) + "回调成功")


@log('court')
def court(data):
    """
    """
    rootpath = os.getcwd()
    id = data['id']
    client = data['client']
    datafile = data['datafile']
    callbackurl = data["callbackurl"]
    mkdir(["static", "court", client, str(id)])
    courtpath = "static/court/" + client + "/" + str(id)
    urllib.urlretrieve(datafile, courtpath + "/" + os.path.basename(datafile))  # 下载文件

    try:
        # 开始计算
        os.chdir(rootpath + "/code")
        matlabapp = matlab.engine.start_matlab()
        res = matlabapp.Stadium(rootpath + "/" + courtpath + "/", "border-src.txt", "border-dest.txt", nargout=0)
    except:
        data = {"code": 2001, "msg": "球场计算失败", "id": id}
    else:
        data = {"code": 200, "msg": "球场计算成功", "id": id,
                "datafile": config.MATLAB_WEB_HOST + "/" + courtpath + "/border-dest.txt"}

    os.chdir(rootpath)
    try:
        urllib2.urlopen(url=callbackurl, data=urllib.urlencode(data))
    except:
        log_text("球场:" + str(id) + "回调失败")
    else:
        log_text("球场:" + str(id) + "回调成功")


# 计算比赛的队列
def callback_match(ch, method, properties, body):
    print('match')
    body = json.loads(body)
    print(body)
    match(body)
    print('match finished')

# 计算球场的队列
def callback_court(ch, method, properties, body):
    body = json.loads(body)
    print(body)
    court(body)
    print('court finished')


@log('test')
def callback_test(ch, method, properties, body):
    print(body)
    try:
        matlabapp = matlab.engine.start_matlab()
        print("matlab stared")
        log_text("matlab stared")
    except:
        log_text(traceback.format_exc())
        print('start error')


def runrabbitmq():
    credentials = pika.PlainCredentials(config.MQ_USER, config.MQ_PASSWORD)
    connection = pika.BlockingConnection(pika.ConnectionParameters(host=config.MQ_HOST, credentials=credentials))
    channel = connection.channel()

    channel.queue_declare(queue='match')
    channel.queue_declare(queue='court')
    channel.queue_declare(queue='test')
    channel.basic_consume(queue="match", auto_ack=True, on_message_callback=callback_match)
    channel.basic_consume(queue="court", auto_ack=True, on_message_callback=callback_court)
    channel.basic_consume(queue="test", auto_ack=True, on_message_callback=callback_test)
    print(' [*] Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()


if __name__ == "__main__":
    # matlabapp = matlab.engine.start_matlab()
    log_text("app init")
    runrabbitmq()
